#include <iostream>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "String.hpp"

using namespace xml;

String::String(){
//	m_str = NULL;
//	m_len = 0;
}

String::String(const char *st){

	m_str = st;
	/*
	cout << " char const \n";
	m_len = strlen(st);
	if (m_len){
		m_str = new char[m_len + 1];
		strcpy (m_str, st);
		m_str[m_len] = '\0';
	}
	cout << " char const end \n";
	*/
}

String::String(const String &st){

	m_str = st;
	/*
	cout << " copy const : " << st.length() << endl ;
	m_len = st.length();
	if (m_len){
		m_str = new char[m_len + 1];
		strcpy (m_str, st.c_str());
		m_str[m_len] = '\0';
	}else
		m_str = NULL;
	cout << " copy const end \n";
	*/
}

String::~String(){
	//delete [] m_str;
	//m_str = NULL;
}

int String::length() const{
	return m_str.length();
}

const char* String::c_str() const{
	//char *t = NULL;
	//cout << " c_str()  NULL: " << t << endl;
	return m_str.c_str();
}

void String::assign(const String st ){
	
	m_str.assign(st);
	/*
	cout << " string assign \n";
	if (m_str){
		delete [] m_str;
		m_str = NULL;
	}
	
	m_len = st.length();
	if (m_len){
		m_str = new char[m_len + 1];
		strcpy (m_str, st.c_str());
	}	
	//m_str[st.length()] = '\0'; // No Need to do this
	cout << " string assign end\n";
	*/
}

void String::assign(const char *st ){
	
	m_str.assign(st);
	/*
	cout << " char assign \n";
	if (m_str){
		delete [] m_str;
		m_str = NULL;
	}
	
	m_len = strlen(st);
	if (m_len){
		m_str = new char[m_len + 1];
		strcpy (m_str, st);
		m_str[m_len] = '\0';
	}	
	cout << " char assign end \n";
	*/
}

void String::clear(){

	m_str.clear();
	/*
	cout << " clear \n";
	if (m_str){
		delete [] m_str;
		m_str = NULL;
	}	
	m_len = 0;
	cout << " clear end \n";
	*/
}

int String::compare (const String st){

	return m_str.compare(st);
	/*
	cout << " compare \n";
	return strcmp(m_str, st.c_str());
	*/
}

const String& String::operator+= (const char ch){
	
	m_str += ch;
	/*
	cout << "+= operator \n";
	m_str = (char *) realloc (m_str, (m_len + 1) * sizeof(char));
	if (!m_str){
		cout << "Can't allocate more space " << endl;
		assert(false);
	}
	else{
		m_str[m_len ] = ch;
		m_len += 1;
		m_str[m_len ] = '\0';
	}
	*/
	return *this;
}

//namespace xml {
	const String String::operator+(const String& s1) const {

		std::string s;
		s = m_str + s1.c_str();
		String tmp(s.c_str());
		/*
		cout << "+ operator \n";
		int t_len = s1.length() + s2.length() + 1;
		if ((s1.length() + s2.length())){
			char *tmp = new char[t_len];

			strcpy (tmp, s1.c_str());
			strcat (tmp, s2.c_str());
			tmp[t_len] = '\0';

			String t_str ;
			t_str.assign(tmp);

			delete [] tmp;
			tmp = NULL;

			return t_str;
		}
		else{
			String s;
			return s;
		}*/
		return tmp;
	}

	
//}

std::ostream &operator<<(std::ostream &out, const xml::String &st){
	//printf (" ostream operator\n");
	out << st.c_str();
	//printf (" ostream operator end\n");
	return out;
}

String & String::operator=(const String &st){
	m_str = st.c_str();
	/*
	cout << "String assign  operator \n";
	if (m_str){
		delete [] m_str;
		m_str = NULL;
		m_len = 0;
	}
	m_len = st.length();
	if (m_len){
		m_str = new char[m_len + 1];
		strcpy (m_str, st.c_str());
		m_str[m_len] = '\0';
	}
	cout << "String assign  operator end\n";
	return *this;
	*/
	return *this;
}

String &String::operator=(const char &ch){

	m_str = ch;
	/*
	cout << "char assign operator \n";
	if (m_str){
		delete [] m_str;
		m_str = NULL;
		m_len = 0;
	}
	m_len = 1;
	m_str = new char[m_len + 1];
	m_str[0] = ch;
	m_str[m_len] = '\0';
	cout << "char assign operator end\n";
	return *this;
	*/
	return *this;
}

String::operator std::string() const {

	//cout << "conversion operator \n";
	std::string tmp(m_str);
	//strcpy (tmp.c_str(), m_str);
	//cout << "conversion operator end\n";
	return tmp;
	 
}

